package jumpingnotes.restlet.resource;

import static jumpingnotes.restlet.ErrorCode.*;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import jumpingnotes.restlet.JsonMapping;
import jumpingnotes.service.QueryService;

import org.json.JSONObject;
import org.restlet.Context;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.resource.Representation;
import org.restlet.resource.ResourceException;
import org.restlet.resource.Variant;

public class FindAllResource extends BaseResource
{
	private Class<?> type = null;
	private int startIndex = 0;
	private int count = 10;

	@Override
	public void init(Context context, Request request, Response response)
	{
		super.init(context, request, response);

		getVariants().add(new Variant(MediaType.APPLICATION_JSON));

		try
		{
			sessionId = (String) getRequest().getAttributes().get("sessionId");
			checkPermission();

			if (hasPermission())
			{
				// URL: "/{types}/all?startIndex={startIndex}&amp;count={count}"
				String typesStr = (String) getRequest().getAttributes().get("types");
				String startIndexStr = (String) getRequest().getAttributes().get("startIndex");
				String countStr = (String) getRequest().getAttributes().get("count");

				type = getTypeByName(typesStr);
				startIndex = Integer.valueOf(startIndexStr);
				count = Integer.valueOf(countStr);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	@Override
	public Representation represent(Variant variant) throws ResourceException
	{
		if (!hasPermission())
		{
			return createErrorRepresentation(NO_PERMISSION);
		}

		if (type == null)
		{
			return createErrorRepresentation(OBJECT_NOT_FOUND);
		}

		try
		{
			// get all object
			String methodName = "findAll" + type.getSimpleName();
			Method method = QueryService.class.getMethod(methodName, int.class, int.class);
			List<?> objectList = (List<?>) method.invoke(service, startIndex, count);

			// get object count
			int objectListSize = ((List<?>) method.invoke(service, -1, -1)).size();

			// create json object
			List<JSONObject> objectJsonList = new ArrayList<JSONObject>();
			for (Object object : objectList)
			{
				JSONObject objectJson = JsonMapping.map(type, object);
				objectJsonList.add(objectJson);
			}

			JSONObject objectsJson = new JSONObject();
			objectsJson.put("count", objectListSize);
			objectsJson.put("objects", objectJsonList);

			return createJsonRepresentation(objectsJson);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return createErrorRepresentation(SERVER_INTERNAL_ERROR);
		}
	}
}
